# -*- coding: UTF-8 -*-

# @Time : 2020/8/24 16:16 

# @Author : litao

# @File : dj_tornado.py

import sys
import os
import os
import django
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
#os.environ.setdefault("DJANGO_SETTINGS_MODULE", "testsite.settings")

import tornado.httpserver
import tornado.ioloop
import tornado.web
from tornado.options import options, define, parse_command_line
import tornado.websocket
import logging
# django settings must be called before importing models
from django.conf import settings
django.setup()


from models import Message, DjForm, GraphLayout
import json
import time
#settings.configure( DATABASE_NAME='dev.db',DATABASE_ENGINE='sqlite3')

from concurrent.futures import ThreadPoolExecutor
from tornado.concurrent import run_on_executor
import asyncio
# Define the class that will respond to the URL
class ListMessagesHandler(tornado.web.RequestHandler):
    def get(self):
        messages = Message.objects.all()

        self.render("templates/index.html", title="My title",
                    messages=messages)
class ListGraphLayoutHandler(tornado.web.RequestHandler):
    def get(self):
        graphlayout = GraphLayout.objects.values()
        data = {}
        data['list'] = list(graphlayout)[0:10]
        items = [json.dumps(dictobj) for dictobj in data['list']]
        self.render("templates/graphlayout.html", title="My title", items=items)
    def post(self):
        graphlayout = GraphLayout.objects.values()
        data = {}
        data['list'] = list(graphlayout)
        self.write(data)
class FormHandler(tornado.web.RequestHandler):
    def get(self):
        form = DjForm()

        self.render("templates/form.html", title="My title", form = form)

    def post(self):

        data = {
            'subject':self.request.arguments['subject'][0],
            'content':self.request.arguments['content'][0],
        }
        form = DjForm(data=data)
        if form.is_valid():
            message = Message(**form.cleaned_data)
            message.save()
            self.redirect('/')
        else:

            self.render("templates/form.html", title="My title", form=form)

def send_message(message):
    for handler in ChatSocketHandler.socket_handlers:
        try:
            handler.write_message(message)
        except:
            logging.error('Error sending message', exc_info=True)
class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('templates/websocket.html')

class ProStatus():
    connector = {}  # 记录当前连接的user

    def user_connect(self, user):
        print(user)
        if user not in self.connector:
            self.connector[user] = set()

    def user_remove(self, user):
        self.connector.pop(user)

    def trigger(self, message):
        ''' 向所有被记录的客户端推送最新内容 '''
        for user in self.connector:
            user.write_message(message)
    def touser(self, user, message):
        ''' 向所有被记录的客户端推送最新内容 '''
        if user in self.connector:
            user.write_message(message)
class ChatSocketHandler(tornado.websocket.WebSocketHandler):
    #socket_handlers = set()

    # @tornado.gen.coroutine
    # def open(self):
    #     ChatSocketHandler.socket_handlers.add(self)
    #     send_message('A new user has entered the chat room.')
    #
    #     tornado.ioloop.IOLoop.instance().add_timeout(time.time() + 10, callback=self.on_message,message='10')
    #
    # def on_close(self):
    #     ChatSocketHandler.socket_handlers.remove(self)
    #     send_message('A user has left the chat room.')
    # def on_message(self, message):
    #     send_message(message)
    # def check_origin(self):
    #     '''重写同源检查 解决跨域问题'''
    #     return True
    executor = ThreadPoolExecutor(4)

    @tornado.gen.coroutine
    def open(self):
        '''新的websocket连接后被调动'''
        ProStatus().user_connect(self)  # 用户连接后记录
        #tornado.ioloop.IOLoop.instance().add_timeout(time.time() + 10, callback=self.on_message, message='10')
        data = {}
        all_done = asyncio.Future()
        tornado.ioloop.IOLoop.instance().add_callback(self.calxml, self.on_message, all_done)
        #self.write_message('123')
        #result = yield all_done
        self.write_message('456')
        #self.write_message(result)

    def on_close(self):
        '''websocket连接关闭后被调用'''
        ProStatus().user_remove(self)  # 断开连接后remove
        print('已存在的数量=',len(ProStatus().connector))
    def on_message(self, message):
        '''接收到客户端消息时被调用'''
        self.write_message(message)

    @run_on_executor
    def calxml(self, func, all_done):
        time.sleep(10)
        result = '123'
        self.write_message(result)
        #func(result)
        #all_done.set_result(result)
class ConnectHandler(tornado.websocket.WebSocketHandler) :
    def check_origin(self, origin) :
        '''重写同源检查 解决跨域问题'''
        return True

    def open(self) :
        '''新的websocket连接后被调动'''
        self.write_message('Welcome')

    def on_close(self) :
        '''websocket连接关闭后被调用'''

    def on_message(self, message) :
        '''接收到客户端消息时被调用'''
        self.write_message('new message :' + message)  # 向客服端发送
# map the Urls to the class
application = tornado.web.Application([
    (r"/", MainHandler),
    (r"/message", ListMessagesHandler),
    (r"/form/", FormHandler),
    (r"/Graph/",ListGraphLayoutHandler),
    (r"/websocket/",ChatSocketHandler),
], compress_response=True,
    autoescape = None,
    #template_path = os.path.join(os.path.dirname(__file__), "templates"),
    static_path = os.path.join(os.path.dirname(__file__), "statics"),
)

# Start the server
if __name__ == "__main__":
    parse_command_line()
    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(8888)
    tornado.ioloop.IOLoop.instance().start()